/**
 * Copyright (C) 2023 maminjie <canpool@163.com>
 * Copyright (C) 2017-2018 Uwe Kindler
 * SPDX-License-Identifier: LGPL-2.1
 **/

#include "QxDockAreaTitleBar.h"
#include "QxDockAutoHideContainer.h"
#include "QxDockAreaTabBar.h"
#include "QxDockAreaTitleBarPrivate.h"
#include "QxDockAreaWidget.h"
#include "QxDockFactory.h"
#include "QxDockFocusController.h"
#include "QxDockManager.h"
#include "QxDockOverlay.h"
#include "QxDockWidget.h"
#include "QxDockWidgetTab.h"
#include "QxDockElidingLabel.h"
#include "QxDockFloatingContainer.h"
#include "QxDockFloatingDragPreview.h"
#include "QxDockIconProvider.h"

#include <QApplication>
#include <QBoxLayout>
#include <QDebug>
#include <QMenu>
#include <QMouseEvent>
#include <QPointer>
#include <QPushButton>
#include <QScrollArea>
#include <QStyle>
#include <QToolButton>
#include <iostream>

QX_BEGIN_NAMESPACE

static const char *const LocationProperty = "Location";

/**
 * Private data class of DockAreaTitleBar class (pimpl)
 */
struct DockAreaTitleBarPrivate {
    DockAreaTitleBar *_this;
    QPointer<tTitleBarButton> TabsMenuButton;
    QPointer<tTitleBarButton> AutoHideButton;
    QPointer<tTitleBarButton> UndockButton;
    QPointer<tTitleBarButton> CloseButton;
    QBoxLayout *Layout;
    DockAreaWidget *dockArea;
    DockAreaTabBar *TabBar;
    DockElidingLabel *AutoHideTitleLabel;
    bool MenuOutdated = true;
    QMenu *TabsMenu;
    QList<tTitleBarButton *> DockWidgetActionsButtons;

    QPoint DragStartMousePos;
    eDragState DragState = DraggingInactive;
    IFloatingWidget *FloatingWidget = nullptr;

    /**
     * Private data constructor
     */
    DockAreaTitleBarPrivate(DockAreaTitleBar *_public);

    /**
     * Creates the title bar close and menu buttons
     */
    void createButtons();

    /**
     * Creates the auto hide title label, only displayed when the dock area is overlayed
     */
    void createAutoHideTitleLabel();

    /**
     * Creates the internal TabBar
     */
    void createTabBar();

    /**
     * Convenience function for dockManager access
     */
    DockManager *dockManager() const
    {
        return dockArea->dockManager();
    }

    /**
     * Returns true if the given config flag is set
     * Convenience function to ease config flag testing
     */
    static bool testConfigFlag(DockManager::eConfigFlag Flag)
    {
        return DockManager::testConfigFlag(Flag);
    }

    /**
     * Returns true if the given config flag is set
     * Convenience function to ease config flag testing
     */
    static bool testAutoHideConfigFlag(DockManager::eAutoHideFlag Flag)
    {
        return DockManager::testAutoHideConfigFlag(Flag);
    }

    /**
     * Test function for current drag state
     */
    bool isDraggingState(eDragState dragState) const
    {
        return this->DragState == dragState;
    }

    /**
     * Starts floating
     */
    void startFloating(const QPoint &Offset);

    /**
     * Makes the dock area floating
     */
    IFloatingWidget *makeAreaFloating(const QPoint &Offset, eDragState DragState);

    /**
     * Helper function to create and initialize the menu entries for
     * the "Auto Hide Group To..." menu
     */
    QAction *createAutoHideToAction(const QString &Title, SideBarLocation Location, QMenu *Menu)
    {
        auto Action = Menu->addAction(Title);
        Action->setProperty("Location", Location);
        QObject::connect(Action, &QAction::triggered, _this, &DockAreaTitleBar::onAutoHideToActionClicked);
        return Action;
    }
};   // struct DockAreaTitleBarPrivate

DockAreaTitleBarPrivate::DockAreaTitleBarPrivate(DockAreaTitleBar *_public) : _this(_public)
{
}

void DockAreaTitleBarPrivate::createButtons()
{
    QSizePolicy ButtonSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);

    // Tabs menu button
    TabsMenuButton = new DockTitleBarButton(testConfigFlag(DockManager::DockAreaHasTabsMenuButton));
    TabsMenuButton->setObjectName("tabsMenuButton");
    TabsMenuButton->setAutoRaise(true);
    TabsMenuButton->setPopupMode(QToolButton::InstantPopup);
    internal::setButtonIcon(TabsMenuButton, QStyle::SP_TitleBarUnshadeButton, Qx::DockAreaMenuIcon);
    QMenu *TabsMenu = new QMenu(TabsMenuButton);
#ifndef QT_NO_TOOLTIP
    TabsMenu->setToolTipsVisible(true);
#endif
    _this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow()));
    TabsMenuButton->setMenu(TabsMenu);
    internal::setToolTip(TabsMenuButton, QObject::tr("List All Tabs"));
    TabsMenuButton->setSizePolicy(ButtonSizePolicy);
    Layout->addWidget(TabsMenuButton, 0);
    _this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction *)), SLOT(onTabsMenuActionTriggered(QAction *)));

    // Undock button
    UndockButton = new DockTitleBarButton(testConfigFlag(DockManager::DockAreaHasUndockButton));
    UndockButton->setObjectName("detachGroupButton");
    UndockButton->setAutoRaise(true);
    internal::setToolTip(UndockButton, QObject::tr("Detach Group"));
    internal::setButtonIcon(UndockButton, QStyle::SP_TitleBarNormalButton, Qx::DockAreaUndockIcon);
    UndockButton->setSizePolicy(ButtonSizePolicy);
    Layout->addWidget(UndockButton, 0);
    _this->connect(UndockButton, SIGNAL(clicked()), SLOT(onUndockButtonClicked()));

    // AutoHide Button
    const auto autoHideEnabled = testAutoHideConfigFlag(DockManager::AutoHideFeatureEnabled);
    AutoHideButton =
        new DockTitleBarButton(testAutoHideConfigFlag(DockManager::DockAreaHasAutoHideButton) && autoHideEnabled);
    AutoHideButton->setObjectName("dockAreaAutoHideButton");
    AutoHideButton->setAutoRaise(true);
    internal::setToolTip(AutoHideButton, _this->titleBarButtonToolTip(TitleBarButtonAutoHide));
    internal::setButtonIcon(AutoHideButton, QStyle::SP_DialogOkButton, Qx::AutoHideIcon);
    AutoHideButton->setSizePolicy(ButtonSizePolicy);
    AutoHideButton->setCheckable(testAutoHideConfigFlag(DockManager::AutoHideButtonCheckable));
    AutoHideButton->setChecked(false);
    Layout->addWidget(AutoHideButton, 0);
    _this->connect(AutoHideButton, SIGNAL(clicked()), SLOT(onAutoHideButtonClicked()));

    // Close button
    CloseButton = new DockTitleBarButton(testConfigFlag(DockManager::DockAreaHasCloseButton));
    CloseButton->setObjectName("dockAreaCloseButton");
    CloseButton->setAutoRaise(true);
    internal::setButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton, Qx::DockAreaCloseIcon);
    internal::setToolTip(CloseButton, _this->titleBarButtonToolTip(TitleBarButtonClose));
    CloseButton->setSizePolicy(ButtonSizePolicy);
    CloseButton->setIconSize(QSize(16, 16));
    Layout->addWidget(CloseButton, 0);
    _this->connect(CloseButton, SIGNAL(clicked()), SLOT(onCloseButtonClicked()));
}

void DockAreaTitleBarPrivate::createAutoHideTitleLabel()
{
    AutoHideTitleLabel = new DockElidingLabel("");
    AutoHideTitleLabel->setObjectName("autoHideTitleLabel");
    Layout->addWidget(AutoHideTitleLabel);
}

void DockAreaTitleBarPrivate::createTabBar()
{
    TabBar = componentsFactory()->createDockAreaTabBar(dockArea);
    TabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
    Layout->addWidget(TabBar);
    _this->connect(TabBar, SIGNAL(tabClosed(int)), SLOT(markTabsMenuOutdated()));
    _this->connect(TabBar, SIGNAL(tabOpened(int)), SLOT(markTabsMenuOutdated()));
    _this->connect(TabBar, SIGNAL(tabInserted(int)), SLOT(markTabsMenuOutdated()));
    _this->connect(TabBar, SIGNAL(removingTab(int)), SLOT(markTabsMenuOutdated()));
    _this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(markTabsMenuOutdated()));
    _this->connect(TabBar, SIGNAL(currentChanged(int)), SLOT(onCurrentTabChanged(int)));
    _this->connect(TabBar, SIGNAL(tabBarClicked(int)), SIGNAL(tabBarClicked(int)));
    _this->connect(TabBar, SIGNAL(elidedChanged(bool)), SLOT(markTabsMenuOutdated()));
}

IFloatingWidget *DockAreaTitleBarPrivate::makeAreaFloating(const QPoint &Offset, eDragState DragState)
{
    QSize Size = dockArea->size();
    this->DragState = DragState;
    bool CreateFloatingDockContainer = (DraggingFloatingWidget != DragState);
    DockFloatingContainer *FloatingDockContainer = nullptr;
    IFloatingWidget *FloatingWidget;
    if (CreateFloatingDockContainer) {
        if (dockArea->autoHideDockContainer()) {
            dockArea->autoHideDockContainer()->cleanupAndDelete();
        }
        FloatingWidget = FloatingDockContainer = new DockFloatingContainer(dockArea);
    } else {
        auto w = new DockFloatingDragPreview(dockArea);
        QObject::connect(w, &DockFloatingDragPreview::draggingCanceled, [=]() {
            this->DragState = DraggingInactive;
        });
        FloatingWidget = w;
    }

    FloatingWidget->startFloating(Offset, Size, DragState, nullptr);
    if (FloatingDockContainer) {
        auto TopLevelDockWidget = FloatingDockContainer->topLevelDockWidget();
        if (TopLevelDockWidget) {
            TopLevelDockWidget->emitTopLevelChanged(true);
        }
    }

    return FloatingWidget;
}

void DockAreaTitleBarPrivate::startFloating(const QPoint &Offset)
{
    if (dockArea->autoHideDockContainer()) {
        dockArea->autoHideDockContainer()->hide();
    }
    FloatingWidget = makeAreaFloating(Offset, DraggingFloatingWidget);
    qApp->postEvent(dockArea, new QEvent((QEvent::Type)internal::DockedWidgetDragStartEvent));
}

DockAreaTitleBar::DockAreaTitleBar(DockAreaWidget *parent) : QFrame(parent), d(new DockAreaTitleBarPrivate(this))
{
    d->dockArea = parent;

    setObjectName("dockAreaTitleBar");
    d->Layout = new QBoxLayout(QBoxLayout::LeftToRight);
    d->Layout->setContentsMargins(0, 0, 0, 0);
    d->Layout->setSpacing(0);
    setLayout(d->Layout);
    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

    d->createTabBar();
    d->createAutoHideTitleLabel();
    d->AutoHideTitleLabel->setVisible(false);   // Default hidden
    d->Layout->addWidget(new DockSpacerWidget(this));
    d->createButtons();

    setFocusPolicy(Qt::NoFocus);
}

DockAreaTitleBar::~DockAreaTitleBar()
{
    if (!d->CloseButton.isNull()) {
        delete d->CloseButton;
    }

    if (!d->TabsMenuButton.isNull()) {
        delete d->TabsMenuButton;
    }

    if (!d->UndockButton.isNull()) {
        delete d->UndockButton;
    }
    delete d;
}

DockAreaTabBar *DockAreaTitleBar::tabBar() const
{
    return d->TabBar;
}

void DockAreaTitleBar::markTabsMenuOutdated()
{
    if (DockAreaTitleBarPrivate::testConfigFlag(DockManager::DockAreaDynamicTabsMenuButtonVisibility)) {
        bool hasElidedTabTitle = false;
        for (int i = 0; i < d->TabBar->count(); ++i) {
            if (!d->TabBar->isTabOpen(i)) {
                continue;
            }
            DockWidgetTab *Tab = d->TabBar->tab(i);
            if (Tab->isTitleElided()) {
                hasElidedTabTitle = true;
                break;
            }
        }
        bool visible = (hasElidedTabTitle && (d->TabBar->count() > 1));
        QMetaObject::invokeMethod(d->TabsMenuButton, "setVisible", Qt::QueuedConnection, Q_ARG(bool, visible));
    }
    d->MenuOutdated = true;
}

void DockAreaTitleBar::onTabsMenuAboutToShow()
{
    if (!d->MenuOutdated) {
        return;
    }

    QMenu *menu = d->TabsMenuButton->menu();
    menu->clear();
    for (int i = 0; i < d->TabBar->count(); ++i) {
        if (!d->TabBar->isTabOpen(i)) {
            continue;
        }
        auto Tab = d->TabBar->tab(i);
        QAction *Action = menu->addAction(Tab->icon(), Tab->text());
        internal::setToolTip(Action, Tab->toolTip());
        Action->setData(i);
    }

    d->MenuOutdated = false;
}

void DockAreaTitleBar::onCloseButtonClicked()
{
    QX_DOCK_PRINT("DockAreaTitleBar::onCloseButtonClicked");
    if (DockManager::testAutoHideConfigFlag(DockManager::AutoHideCloseButtonCollapsesDock) &&
        d->dockArea->autoHideDockContainer()) {
        d->dockArea->autoHideDockContainer()->collapseView(true);
    } else if (d->testConfigFlag(DockManager::DockAreaCloseButtonClosesTab)) {
        d->TabBar->closeTab(d->TabBar->currentIndex());
    } else {
        d->dockArea->closeArea();
    }
}

void DockAreaTitleBar::onUndockButtonClicked()
{
    if (d->dockArea->features().testFlag(DockWidget::DockWidgetFloatable)) {
        d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
    }
}

void DockAreaTitleBar::onTabsMenuActionTriggered(QAction *Action)
{
    int Index = Action->data().toInt();
    d->TabBar->setCurrentIndex(Index);
    Q_EMIT tabBarClicked(Index);
}

void DockAreaTitleBar::updateDockWidgetActionsButtons()
{
    auto Tab = d->TabBar->currentTab();
    if (!Tab) {
        return;
    }

    DockWidget *dockWidget = Tab->dockWidget();
    if (!d->DockWidgetActionsButtons.isEmpty()) {
        for (auto Button : d->DockWidgetActionsButtons) {
            d->Layout->removeWidget(Button);
            delete Button;
        }
        d->DockWidgetActionsButtons.clear();
    }

    auto Actions = dockWidget->titleBarActions();
    if (Actions.isEmpty()) {
        return;
    }

    int InsertIndex = indexOf(d->TabsMenuButton);
    for (auto Action : Actions) {
        auto Button = new DockTitleBarButton(true, this);
        Button->setDefaultAction(Action);
        Button->setAutoRaise(true);
        Button->setPopupMode(QToolButton::InstantPopup);
        Button->setObjectName(Action->objectName());
        d->Layout->insertWidget(InsertIndex++, Button, 0);
        d->DockWidgetActionsButtons.append(Button);
    }
}

void DockAreaTitleBar::onCurrentTabChanged(int Index)
{
    if (Index < 0) {
        return;
    }

    if (d->testConfigFlag(DockManager::DockAreaCloseButtonClosesTab)) {
        DockWidget *dockWidget = d->TabBar->tab(Index)->dockWidget();
        d->CloseButton->setEnabled(dockWidget->features().testFlag(DockWidget::DockWidgetClosable));
    }

    updateDockWidgetActionsButtons();
}

void DockAreaTitleBar::onAutoHideButtonClicked()
{
    if (DockManager::testAutoHideConfigFlag(DockManager::AutoHideButtonTogglesArea) ||
        qApp->keyboardModifiers().testFlag(Qt::ControlModifier)) {
        d->dockArea->toggleAutoHide();
    } else {
        d->dockArea->currentDockWidget()->toggleAutoHide();
    }
}

void DockAreaTitleBar::onAutoHideDockAreaActionClicked()
{
    d->dockArea->toggleAutoHide();
}

void DockAreaTitleBar::onAutoHideToActionClicked()
{
    int Location = sender()->property(LocationProperty).toInt();
    d->dockArea->toggleAutoHide((SideBarLocation)Location);
}

QAbstractButton *DockAreaTitleBar::button(TitleBarButton which) const
{
    switch (which) {
    case TitleBarButtonTabsMenu:
        return d->TabsMenuButton;
    case TitleBarButtonUndock:
        return d->UndockButton;
    case TitleBarButtonClose:
        return d->CloseButton;
    case TitleBarButtonAutoHide:
        return d->AutoHideButton;
    default:
        return nullptr;
    }
}

DockElidingLabel *DockAreaTitleBar::autoHideTitleLabel() const
{
    return d->AutoHideTitleLabel;
}

void DockAreaTitleBar::setVisible(bool Visible)
{
    Super::setVisible(Visible);
    markTabsMenuOutdated();
}

void DockAreaTitleBar::mousePressEvent(QMouseEvent *ev)
{
    if (ev->button() == Qt::LeftButton) {
        ev->accept();
        d->DragStartMousePos = ev->pos();
        d->DragState = DraggingMousePressed;

        if (DockManager::testConfigFlag(DockManager::FocusHighlighting)) {
            d->dockManager()->dockFocusController()->setDockWidgetTabFocused(d->TabBar->currentTab());
        }
        return;
    }
    Super::mousePressEvent(ev);
}

void DockAreaTitleBar::mouseReleaseEvent(QMouseEvent *ev)
{
    if (ev->button() == Qt::LeftButton) {
        QX_DOCK_PRINT("DockAreaTitleBar::mouseReleaseEvent");
        ev->accept();
        auto CurrentDragState = d->DragState;
        d->DragStartMousePos = QPoint();
        d->DragState = DraggingInactive;
        if (DraggingFloatingWidget == CurrentDragState) {
            d->FloatingWidget->finishDragging();
        }

        return;
    }
    Super::mouseReleaseEvent(ev);
}

void DockAreaTitleBar::mouseMoveEvent(QMouseEvent *ev)
{
    Super::mouseMoveEvent(ev);
    if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive)) {
        d->DragState = DraggingInactive;
        return;
    }

    // move floating window
    if (d->isDraggingState(DraggingFloatingWidget)) {
        d->FloatingWidget->moveFloating();
        return;
    }

    // If this is the last dock area in a floating dock container it does not make
    // sense to move it to a new floating widget and leave this one
    // empty
    if (d->dockArea->dockContainer()->isFloating() && d->dockArea->dockContainer()->visibleDockAreaCount() == 1 &&
        !d->dockArea->isAutoHide()) {
        return;
    }

    // If one single dock widget in this area is not floatable then the whole
    // area is not floatable
    // We can create the floating drag preview if the dock widget is movable
    auto Features = d->dockArea->features();
    if (!Features.testFlag(DockWidget::DockWidgetFloatable) && !(Features.testFlag(DockWidget::DockWidgetMovable))) {
        return;
    }

    int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength();
    if (DragDistance >= DockManager::startDragDistance()) {
        QX_DOCK_PRINT("DockAreaTitleBar::startFloating");
        d->startFloating(d->DragStartMousePos);
        auto Overlay = d->dockArea->dockManager()->containerOverlay();
        Overlay->setAllowedAreas(OuterDockAreas);
    }

    return;
}

void DockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
    // If this is the last dock area in a dock container it does not make
    // sense to move it to a new floating widget and leave this one
    // empty
    if (d->dockArea->dockContainer()->isFloating() && d->dockArea->dockContainer()->dockAreaCount() == 1) {
        return;
    }

    if (!d->dockArea->features().testFlag(DockWidget::DockWidgetFloatable)) {
        return;
    }

    d->makeAreaFloating(event->pos(), DraggingInactive);
}

void DockAreaTitleBar::contextMenuEvent(QContextMenuEvent *ev)
{
    ev->accept();
    if (d->isDraggingState(DraggingFloatingWidget)) {
        return;
    }

    const bool isAutoHide = d->dockArea->isAutoHide();
    const bool isTopLevelArea = d->dockArea->isTopLevelArea();
    QAction *Action;
    QMenu Menu(this);
    if (!isTopLevelArea) {
        Action = Menu.addAction(isAutoHide ? tr("Detach") : tr("Detach Group"), this, SLOT(onUndockButtonClicked()));
        Action->setEnabled(d->dockArea->features().testFlag(DockWidget::DockWidgetFloatable));
        if (DockManager::testAutoHideConfigFlag(DockManager::AutoHideFeatureEnabled)) {
            Action = Menu.addAction(isAutoHide ? tr("Unpin (Dock)") : tr("Pin Group"), this,
                                    SLOT(onAutoHideDockAreaActionClicked()));
            auto AreaIsPinnable = d->dockArea->features().testFlag(DockWidget::DockWidgetPinnable);
            Action->setEnabled(AreaIsPinnable);

            if (!isAutoHide) {
                auto menu = Menu.addMenu(tr("Pin Group To..."));
                menu->setEnabled(AreaIsPinnable);
                d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
                d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
                d->createAutoHideToAction(tr("Right"), SideBarRight, menu);
                d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
            }
        }
        Menu.addSeparator();
    }
    Action = Menu.addAction(isAutoHide ? tr("Close") : tr("Close Group"), this, SLOT(onCloseButtonClicked()));
    Action->setEnabled(d->dockArea->features().testFlag(DockWidget::DockWidgetClosable));
    if (!isAutoHide && !isTopLevelArea) {
        Action = Menu.addAction(tr("Close Other Groups"), d->dockArea, SLOT(closeOtherAreas()));
    }
    Menu.exec(ev->globalPos());
}

void DockAreaTitleBar::insertWidget(int index, QWidget *widget)
{
    d->Layout->insertWidget(index, widget);
}

int DockAreaTitleBar::indexOf(QWidget *widget) const
{
    return d->Layout->indexOf(widget);
}

QString DockAreaTitleBar::titleBarButtonToolTip(TitleBarButton Button) const
{
    switch (Button) {
    case TitleBarButtonAutoHide:
        if (d->dockArea->isAutoHide()) {
            return tr("Unpin (Dock)");
        }

        if (DockManager::testAutoHideConfigFlag(DockManager::AutoHideButtonTogglesArea)) {
            return tr("Pin Group");
        } else {
            return tr("Pin Active Tab (Press Ctrl to Pin Group)");
        }
        break;

    case TitleBarButtonClose:
        if (d->dockArea->isAutoHide()) {
            return tr("Close");
        }

        if (DockManager::testConfigFlag(DockManager::DockAreaCloseButtonClosesTab)) {
            return tr("Close Active Tab");
        } else {
            return tr("Close Group");
        }
        break;

    default:
        break;
    }

    return QString();
}

DockTitleBarButton::DockTitleBarButton(bool visible, QWidget *parent)
    : tTitleBarButton(parent), Visible(visible),
      HideWhenDisabled(DockManager::testConfigFlag(DockManager::DockAreaHideDisabledButtons))
{
    setFocusPolicy(Qt::NoFocus);
}

void DockTitleBarButton::setVisible(bool visible)
{
    // 'visible' can stay 'true' if and only if this button is configured to generaly visible:
    visible = visible && this->Visible;

    // 'visible' can stay 'true' unless: this button is configured to be invisible when it is disabled and it is
    // currently disabled:
    if (visible && HideWhenDisabled) {
        visible = isEnabled();
    }

    Super::setVisible(visible);
}

bool DockTitleBarButton::event(QEvent *ev)
{
    if (QEvent::EnabledChange == ev->type() && HideWhenDisabled) {
        // force setVisible() call
        // Calling setVisible() directly here doesn't work well when button is expected to be shown first time
        QMetaObject::invokeMethod(this, "setVisible", Qt::QueuedConnection, Q_ARG(bool, isEnabled()));
    }

    return Super::event(ev);
}

DockSpacerWidget::DockSpacerWidget(QWidget *Parent /*= 0*/) : Super(Parent)
{
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    setStyleSheet("border: none; background: none;");
}

QX_END_NAMESPACE
